

*------------------------------------------------------------------------------------------------*
*** Presidential Rallies and Electoral Outcomes in Multiparty Systems: Evidence from Argentina ***
*------------------------------------------------------------------------------------------------*

*************************
* FIGURE 1: Google Trends
*************************
clear
use gt_base.dta
* 0) Typos and IDs
capture confirm numeric variable treated
if _rc destring treated, replace
capture confirm numeric variable week_bin
if _rc destring week_bin, replace
capture confirm numeric variable score
* Destring score, replace
capture confirm numeric variable city
if _rc encode city_id, gen(city)
* 1) Pre-treatment period
bys city: egen has_base = max(week_bin==-1 & !missing(score))
keep if has_base
* 2) Dummies per period
capture drop Dm3 Dm2 Dp1 Tm3 Tm2 Tp1
gen byte   Dm3 = (week_bin==-3)
gen byte   Dm2 = (week_bin==-2)
gen byte   Dp0 = (week_bin== 0)
* 3) Interactions
gen double Tm3 = treated*Dm3   // lead -3 vs base (-1)
gen double Tm2 = treated*Dm2   // lead -2 vs base (-1)
gen double Tp0 = treated*Dp0   // post +1 vs base (-1)
* 4) Estimation
xtset city week_bin
xtreg score Tm3 Tm2 Tp0 Dm3 Dm2 Dp0, fe cluster(city)
estimates store ES
* ====== Build dataset (τ = -3, -2, -1(base), +1) ======
preserve
clear
set obs 4
gen tau = .
replace tau = -3 in 1
replace tau = -2 in 2
replace tau = -1 in 3
replace tau =  0 in 4
gen b  = .
replace b = _b[Tm3] in 1     // coef lead -3
replace b = _b[Tm2] in 2     // coef lead -2
replace b = 0       in 3     // base -1 fix in 0
replace b = _b[Tp0] in 4     // coef post +1
gen se = .
replace se = _se[Tm3] in 1
replace se = _se[Tm2] in 2
*
replace se = _se[Tp0] in 4
scalar z = invnormal(0.975)
gen hi = b + z*se
gen lo = b - z*se
* ====== Graph ======
twoway ///
    (rcap hi lo tau if tau!=-1, lcolor(black) lwidth(thin)) ///
    (scatter b tau, msymbol(O) mcolor(black) msize(medium)), ///
    xlabel(-3 "-3" -2 "-2" -1 "-1" 0 "0", labsize(small)) ///
    xscale(range(-3.5 0.5)) ///
	  xline(-0.5, lpattern(dash) lcolor(gs8) lwidth(thin)) /// 
    yline(0, lcolor(maroon) lwidth(medthick)) ///
    xtitle("Weeks to SSP") ytitle("Google searches for Mauricio Macri (SVI)") ///
    ylabel(, angle(horizontal) grid glcolor(white) glwidth(vthin)) ///
    plotregion(fcolor(gs13) lcolor(none)) graphregion(color(white) lcolor(none)) ///
    legend(off) name(es_week, replace)


**************************************************************
* TABLE 1: Effect of SSP on Juntos por el Cambio's Vote Shares
**************************************************************
clear
use base.dta
* Baseline
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* Economic covariates
xtreg votos_cambiemos_share did treatment treated lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* Excluding CABA
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
* Excluding small. departments 
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
restore 
* Keep provinces with SSP rallies
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
restore 
* Controllin for Alberto Fernández vistis
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)



*********************************************
* TABLE 2: Placebos and Identification Checks
*********************************************
clear
use base.dta
* Provincial elections 
xtreg cambiemos_share_prov did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
preserve
drop if missing(cambiemos_share_prov)
sum cambiemos_share_prov
restore
* 2015 election
xtreg votos_cambiemos_2015 did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_2015
* 2017 election
xtreg votos_cambiemos_2017 did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_2017
* First debate
preserve
gen did_debate1 = treatment * treated_debate1
drop if (treated == 1 & treated_debate1 == 0)
xtreg votos_cambiemos_share did_debate1 treatment treated_debate1 i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Second debate
preserve
gen did_debate2 = treatment * treated_debate2
drop if (treated == 1 & treated_debate2 == 0)
xtreg votos_cambiemos_share did_debate2 treatment treated_debate2 i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore


*******************************************************
* TABLE 3: Mobilization & Demobilization Effects of SSP
*******************************************************
clear
use base.dta
* Turnout
xtreg turnout did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
* Below Median (2015)
preserve
keep if cambiemos_2015 <= -.02194601
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Above Median (2015)
preserve
keep if cambiemos_2015 > -.02194601
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Below Median (2017)
preserve
keep if cambiemos_2017 <= -.1047291
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Above Median (2017)
preserve
keep if cambiemos_2017 > -.1047291
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* FdT
xtreg votos_frente_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)


*****************************************
* TABLE 4: Effect of SSP on Minor Parties
*****************************************
clear
use base.dta
* Minor parties
xtreg votos_otros_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* CF
xtreg votos_consenso_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* NOS
xtreg votos_nos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* UNITE
xtreg votos_unite_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
* Left
xtreg votos_izquierda_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_frente_share votos_otros_share votos_consenso_share votos_nos_share votos_unite_share votos_izquierda_share


*****************************************
* TABLE 5: Effect of SSP on Google Trends
*****************************************
* Pre-treatment: 1/9 al 18/9; post-treatment: 19/9-26/10
clear
use gt_macri_1
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score
* Pre-treatment: 1/9-18/9; post-treatment: 26/9-26/10
clear
use gt_macri_2
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score
* Pre-treatment: 1/9-18/9; post-treatment: 3/10-26/10. 
clear
use gt_macri_3
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score
* Pre-treatment: 1/9-18/9; contra 10/10-26/10
clear
use gt_macri_4
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score
* Placebo - Alberto Fernández
clear
use gt_af
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score
* Placebo - Cristina Fernández
clear
use gt_cf
xtset unit_id treatment
encode(provincia), gen(province)
xtreg score did treatment treated i.province#i.treatment, fe cluster(unit_id)
sum score



**********************************************************************************************************************************************************
*** APPENDIX ***
**********************************************************************************************************************************************************



********************************************
* FIGURA A1: Treated and Control Departments
********************************************


************************************
* FIGURE A2: Excluding each province 
************************************
clear
use base.dta
ssc install coefplot, replace
local state "CABA BuenosAires Catamarca Córdoba Corrientes Chaco Chubut EntreRíos Formosa Jujuy LaPampa LaRioja Mendoza Misiones Neuquén RíoNegro Salta SanJuan SanLuis SantaCruz SantaFe SantiagodelEstero Tucumán TierradelFuego  " 
forvalues i = 1/24 {
 quietly xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron] if distrito_id !=`i', fe cluster(unit_id)
  estimates store state_`i'
  }
coefplot (state_*), keep(did) asequation swapnames vertical ///
	    eqrename( state_1="CABA" state_2="Buenos Aires" state_3="Catamarca" state_4="Córdoba" ///
              state_5="Corrientes" state_6="Chaco" state_7="Chubut" state_8="Entre Ríos" ///
              state_9="Formosa" state_10="Jujuy" state_11="La Pampa" state_12="La Rioja" ///
              state_13="Mendoza" state_14="Misiones" state_15="Neuquén" state_16="Río Negro" ///
              state_17="Salta" state_18="San Juan" state_19="San Luis" state_20="Santa Cruz" ///
              state_21="Santa Fe" state_22="Santiago del Estero" state_23="Tucumán" state_24="Tierra del Fuego") ///
    /// 
    msymbol(O) mcolor(black) msize(medium) ///
    ciopts(recast(rcap) lcolor(black) lwidth(thin)) ///
    /// 
    yscale(range(-.01 .06)) ///
    ylabel(-.01(.01).06, angle(horizontal) grid glcolor(white) glwidth(vthin)) ///
    yline(0, lcolor(maroon) lwidth(medthick)) ///
    xlabel(, angle(90) labsize(small)) ///
    xtitle("Excluded Province") ytitle("Effect of SSP") ///
    /// 
    plotregion(fcolor(gs13) lcolor(none)) ///
    graphregion(color(white) lcolor(none)) ///
    legend(off)


************************************
* FIGURE A3: Randomization Inference
************************************
clear
use base.dta
* 1) Observed t-stat under your baseline spec
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], ///
    fe vce(cluster unit_id)
scalar b_obs = _b[did]
scalar se_obs = _se[did]
scalar t_obs = b_obs / se_obs
* 2) Build unit-level file for stratified randomization (ONE row per unit)
preserve
    keep unit_id province treated
    bys unit_id: keep if _n==1
    egen strata = group(province)
    bys strata: egen n_treat_strata = total(treated)
    tempfile units
    save `units', replace
restore
* 3) Save full panel once
tempfile panel
save `panel', replace
* 4) Permutation loop: store placebo t-stats
set seed 202509
local R = 1000  
tempname mem
tempfile ri_t
postfile `mem' double tstat using `ri_t', replace
forvalues r = 1/`R' {
    * 4.1) Draw placebo treated within each province stratum
    use `units', clear
    bysort strata: gen u = runiform()
    bysort strata (u): gen placebo_treated = (_n <= n_treat_strata[1])
    keep unit_id placebo_treated
    tempfile placebo
    save `placebo', replace
    * 4.2) Merge to panel and create placebo DID
    use `panel', clear
    merge m:1 unit_id using `placebo', nogen
    gen placebo_did = placebo_treated * treatment
    * 4.3) Re-estimate replacing did/treated by placebo counterparts
    quietly xtreg votos_cambiemos_share placebo_did treatment placebo_treated i.province#i.treatment ///
        [aweight=padron], fe vce(cluster unit_id)
    * 4.4) Store t-stat for placebo_did
    scalar t_pl = _b[placebo_did] / _se[placebo_did]
    post `mem' (t_pl)
}
postclose `mem'
* 5) Randomization p-values for t-stat (two-sided + one-sided), with finite-sample correction
use `ri_t', clear
* Two-sided: |t_placebo| >= |t_obs|
gen ge_two = (abs(tstat) >= abs(t_obs))
qui count if ge_two
local k_two = r(N)
scalar p_two = (`k_two' + 1) / (`R' + 1)
* One-sided: t_placebo >= t_obs
gen ge_one = (tstat >= t_obs)
qui count if ge_one
local k_one = r(N)
scalar p_one = (`k_one' + 1) / (`R' + 1)
di as text "Observed b: " as result b_obs
di as text "Observed se: " as result se_obs
di as text "Observed t: " as result t_obs
di as text "RI p-value (two-sided, t): " as result p_two
di as text "RI p-value (one-sided, t>=t_obs): " as result p_one
* 6) Plot histogram of placebo t-stats with line at observed t
* Choose a bin width 
local bw = 0.25
histogram tstat, percent width(`bw') ///
    xscale(range(-10 10)) ///
    xlabel(-10(2)10) ///
    xtitle("Placebo t-statistics") ytitle("% of permutations") ///
    xline(`=t_obs', lcolor(maroon) lwidth(medthick)) ///
    fcolor(black%20) lcolor(black) lwidth(thin) ///
    ylabel(, angle(horizontal) grid glcolor(white) glwidth(vthin)) ///
    plotregion(fcolor(gs13) lcolor(none)) ///
    graphregion(color(white) lcolor(none)) ///
    legend(off) name(ri_t_hist, replace)


*******************************
* TABLE A1: Treated Departments 
*******************************


**********************************
* TABLE A2: Descriptive Statistics
**********************************
clear
use base.dta 
univar votos_cambiemos_share votos_frente_share votos_consenso_share votos_nos_share votos_unite_share votos_izquierda_share empleo salario_promedio cambiemos_share_prov votos_cambiemos_2015 votos_cambiemos_2017


*************************************
* TABLE A3: Correlates of SSP Rallies
*************************************
clear
use base.dta
keep if treatment == 0
gen gap = votos_cambiemos_share - votos_frente_share
gen lnpadron = log(padron)
reg treated lnpadron turnout jxc_mayor i.province, vce(cluster province) 
reg treated lnpadron turnout jxc_mayor votos_cambiemos_share gap i.province, vce(cluster province)
reg treated lnpadron turnout jxc_mayor votos_cambiemos_share gap votos_cambiemos_2015 votos_cambiemos_2017 i.province, vce(cluster province)
univar treated


*********************************************
* TABLE A4: Controlling for Fernández Rallies
*********************************************
clear
use base.dta
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
xtreg votos_cambiemos_share did treatment treated did_fer lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
restore 
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)


*****************************
* TABLE A5: Fernández Rallies
*****************************
clear
use base.dta
xtreg votos_frente_share did_fer treatment fernandez i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_frente_share
xtreg votos_frente_share did_fer treatment fernandez lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_frente_share
xtreg votos_frente_share did_fer treatment fernandez i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
univar votos_frente_share
preserve
keep if padron > 40000
xtreg votos_frente_share did_fer treatment fernandez i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_frente_share
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_frente_share did treatment fernandez i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_frente_share
restore 


**********************************************
* TABLE A6: Main Specification Without Weights
**********************************************
clear
use base.dta
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment treated lnempleo lnsalario_promedio i.province#i.treatment, fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment if distrito_id !=1, fe cluster(unit_id)
univar votos_cambiemos_share
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
univar votos_cambiemos_share
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
univar votos_cambiemos_share
restore 
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment, fe cluster(unit_id)
univar votos_cambiemos_share


*****************************************************
* TABLE A7: Effect of SSP with Wild Cluster Bootstrap
*****************************************************
clear
use base.dta
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph
xtreg votos_cambiemos_share did treatment treated lnempleo lnsalario_promedio i.province#i.treatment, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment if distrito_id !=1, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph
restore 
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment, fe cluster(unit_id)
boottest did, cluster(unit_id) reps(9999) weight(rademacher) seed(2718) nograph




*******************
* TABLE A12: IV-DiD
******************* 
clear
use base.dta
* Instrument: Z = airport × post
gen ivdid = airport*treatment
* FE province×election 
egen provtime = group(province treatment)
* IV-DiD (2SLS) with department FE + FE prov×time
* ssc install ftools, replace
* ssc install reghdfe, replace
* ssc install ivreghdfe, replace
ivreghdfe votos_cambiemos_share (did = ivdid) [aw=padron], ///
    absorb(unit_id provtime) vce(cluster unit_id) first
sum votos_cambiemos_share
* 2017
ivreghdfe votos_cambiemos_2017 (did = ivdid) [aw=padron], ///
    absorb(unit_id provtime) vce(cluster unit_id) first
sum votos_cambiemos_2017
* 2015
ivreghdfe votos_cambiemos_2015 (did = ivdid) [aw=padron], ///
    absorb(unit_id provtime) vce(cluster unit_id) first
sum votos_cambiemos_2015
* Urbanization
gen urb_post = pct_urb * treatment
ivreghdfe votos_cambiemos_share urb_post (did = ivdid) [aw=padron], ///
    absorb(unit_id provtime) vce(cluster unit_id) first
* First stage
reghdfe did ivdid [aw=padron], absorb(unit_id provtime) vce(cluster unit_id)
sum did
* Reduced form
reghdfe votos_cambiemos_share ivdid [aw=padron], absorb(unit_id provtime) vce(cluster unit_id)
sum votos_cambiemos_share


***********************
* TABLE A13: JxC Mayors
***********************
clear
use base.dta
* Baseline
preserve
keep if jxc_mayor == 1
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Economic controls
preserve
keep if jxc_mayor == 1
xtreg votos_cambiemos_share did treatment treated lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Excluding CABA
preserve
keep if jxc_mayor == 1
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
sum votos_cambiemos_share
restore
* Excluding small departments 
preserve
keep if jxc_mayor == 1
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore 
* Keep provinces with SSP rallies
preserve
keep if jxc_mayor == 1
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore 
* Controlling for Fernández visits
preserve
keep if jxc_mayor == 1
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
sum votos_cambiemos_share
restore



************************************************
* TABLE A13: Spillovers: Treated vs Pure Control
************************************************
clear
use base.dta
drop if spillover == 1
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment treated lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
univar votos_cambiemos_share
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment treated i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
restore 
xtreg votos_cambiemos_share did treatment treated did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share


***********************************************************
* TABLE A14: Spillovers: Indirectly Exposed vs Pure Control
***********************************************************
clear
use base.dta
drop if treated == 1
drop did
gen did = treatment * spillover
xtreg votos_cambiemos_share did treatment spillover i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment spillover lnempleo lnsalario_promedio i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
xtreg votos_cambiemos_share did treatment spillover i.province#i.treatment [aweight=padron] if distrito_id !=1, fe cluster(unit_id)
univar votos_cambiemos_share
preserve
keep if padron > 40000
xtreg votos_cambiemos_share did treatment spillover i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
restore 
preserve
keep if (distrito_id == 1| distrito_id == 2| distrito_id == 4| distrito_id == 21| distrito_id == 8| distrito_id == 13| distrito_id == 23| distrito_id == 15| distrito_id == 17| distrito_id == 14| distrito_id == 6| distrito_id == 10 | distrito_id == 5)
xtreg votos_cambiemos_share did treatment spillover i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share
restore 
xtreg votos_cambiemos_share did treatment spillover did_fer i.province#i.treatment [aweight=padron], fe cluster(unit_id)
univar votos_cambiemos_share



**********************************************************************************************************************************************************
*** Matching and Reweighting Robustness ***
**********************************************************************************************************************************************************

clear
use base.dta

*------------------------------------------------------------
* 1) pre PASO cross section to estimate pscore 
*------------------------------------------------------------
preserve
    keep if treatment==0   // PASO

    * One row for each department
    keep unit_id province treated ///
         votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 ///
         padron jxc_mayor lnempleo lnsalario_promedio ///
         nbi propietario population secundario extranjero edad_65
    duplicates drop unit_id, force

    * 
    gen ln_population = ln(population)

    *--------------------------------------------------------
    * 2) Probit 
    *    Province FE
    *--------------------------------------------------------
    probit treated ///
        votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 ///
        ln_population ///
        jxc_mayor, vce(robust)

    predict pscore, pr

    *--------------------------------------------------------
    * 3) Matching NN(1), no replacement common support
    *--------------------------------------------------------
    capture which psmatch2
    if _rc ssc install psmatch2, replace
    capture which pstest
    if _rc ssc install pstest, replace

	psmatch2 treated, pscore(pscore) neighbor(1) noreplacement  common

    *--------------------------------------------------------

    cap confirm var _support
    if !_rc {
        gen matched = (_support==1) & (treated==1 | (_weight>0 & _weight<.))
    }
    else {
        gen matched = (treated==1 | (_weight>0 & _weight<.))
    }

    * checks
    tab treated
    tab matched treated, missing
    tab _weight if treated==0, missing

    * Balance
    pstest votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 ///
         padron jxc_mayor lnempleo lnsalario_promedio, both

    * Save
    keep unit_id matched _weight pscore
    tempfile matchinfo
    save `matchinfo', replace
restore


*------------------------------------------------------------
* 4) Restrict matched sample in panel
*------------------------------------------------------------
merge m:1 unit_id using `matchinfo', nogen

* Check
tab matched treated, missing

*------------------------------------------------------------
* 5) Main DD in matched sample
*------------------------------------------------------------
xtset unit_id treatment

xtreg votos_cambiemos_share did treatment treated ///
    i.province#i.treatment ///
    [aweight=padron] if matched==1, fe cluster(unit_id)

	
***********
* Kernel DD 
***********
clear
use base.dta
gen margin_share = votos_cambiemos_share - votos_frente_share
* Covariates list
local Xbal votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 ///
           padron jxc_mayor lnempleo lnsalario_promedio nbi ///
           secundario_prop edad_65_prop extranjero_prop

*------------------------------------------------------------
* 1) pre PASO cross section to estimate pscore
*------------------------------------------------------------
preserve
    keep if treatment==0   // PASO

    keep unit_id province treated ///
         votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 margin_share ///
         padron jxc_mayor lnempleo lnsalario_promedio ///
         nbi propietario population secundario extranjero edad_65 ///
         secundario_prop edad_65_prop extranjero_prop

    duplicates drop unit_id, force

    gen ln_population = ln(population)
    gen ln_padron     = ln(padron)

    *--------------------------------------------------------
    * 2) Probit
    *--------------------------------------------------------
    probit treated ///
        votos_cambiemos_share votos_cambiemos_2017 votos_cambiemos_2015 ///
        padron nbi secundario_prop edad_65_prop extranjero_prop ///
        jxc_mayor, vce(robust)

    predict double pscore, pr
	
	*--------------------------------------------
    * Trimming 
    *--------------------------------------------
    quietly summarize pscore if treated==1, detail
    local loT = r(p1)
    local hiT = r(p99)

    quietly summarize pscore if treated==0, detail
    local loC = r(p1)
    local hiC = r(p99)

    local lo = max(`loT', `loC')
    local hi = min(`hiT', `hiC')

    keep if inrange(pscore, `lo', `hi')

    *--------------------------------------------------------
    * 3) Kernel matching + common support
    *--------------------------------------------------------
    capture which psmatch2
    if _rc ssc install psmatch2, replace
    capture which pstest
    if _rc ssc install pstest, replace

    psmatch2 treated, pscore(pscore) kernel bwidth(0.03) common

    *--------------------------------------------------------
    * 4) Sample and weights
    *--------------------------------------------------------
    local eps = 1e-6
    cap confirm var _support
    if !_rc {
        gen matched = (_support==1) & (treated==1 | (_weight>`eps' & _weight<.))
    }
    else {
        gen matched = (treated==1 | (_weight>`eps' & _weight<.))
    }

    * Weight normalization
    count if treated==1 & matched==1
    local NT = r(N)
    quietly sum _weight if treated==0 & matched==1
    local SW = r(sum)

    gen mw = .
    replace mw = 1 if treated==1 & matched==1
    replace mw = _weight * (`NT'/`SW') if treated==0 & matched==1 & _weight<.

    * checks
    tab treated
    tab matched treated, missing
    cap confirm var _support
    if !_rc tab _support treated, missing
    sum _weight if treated==0 & matched==1, detail

    *--------------------------------------------------------
    * Balance 
    *--------------------------------------------------------
    pstest `Xbal', both

    *--------------------------------------------------------
    * Balance AFTER: mean/max |SMD| con pesos kernel (mw)
    * SMD(x) = (mean_T - mean_Cw) / sd_T
    *--------------------------------------------------------
    tempname sum_abs max_abs
    scalar `sum_abs' = 0
    scalar `max_abs' = 0
    local K 0

    foreach v of local Xbal {

        quietly summarize `v' if treated==1 & matched==1
        local mt  = r(mean)
        local sdt = r(sd)

        quietly summarize `v' [aw=mw] if treated==0 & matched==1 & mw<.
        local mcw = r(mean)

        if (`sdt'>0 & `sdt'<.) {
            local smd = abs((`mt' - `mcw')/`sdt')
            scalar `sum_abs' = `sum_abs' + `smd'
            if (`smd' > `max_abs') scalar `max_abs' = `smd'
            local ++K
        }
        else {
            di as text "Warning: SD treated=0 o missing para `v' (salteado en SMD)"
        }
    }

    local k_mean = `=scalar(`sum_abs')/`K''
    local k_max  = `=scalar(`max_abs')'

    di as text "Kernel AFTER balance: mean|SMD|=" %9.4f `k_mean' ///
               "  max|SMD|=" %9.4f `k_max'
    *--------------------------------------------------------

    * Save
    keep unit_id matched mw pscore
    tempfile matchinfo
    save `matchinfo', replace
restore

*------------------------------------------------------------
* 5) Main DD with Kernel wegiths
*------------------------------------------------------------
merge m:1 unit_id using `matchinfo', nogen
tab matched treated, missing

xtset unit_id treatment

* Combined weights
gen w = padron * mw

xtreg votos_cambiemos_share did treatment treated ///
    i.province#i.treatment ///
    [aweight=w] if matched==1, fe cluster(unit_id)

*============================================================
* Diagnostics "SUPPORT AND SAMPLE RETENTION"
* (Kernel matching)
*============================================================

* (A) Treated total (baseline) (pre)
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1
    local T_total = r(N)
restore

* (B) Treated / Controls retained (kernel support) (pre)
preserve
    keep if matched==1
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1
    local T_ret = r(N)
    count if treated==0
    local C_ret = r(N)
restore

* (C) Obs retained y # efective units
local Obs_ret   = e(N)
local Units_ret = e(N_g)

di as text "---- Kernel matching diagnostics ----"
di as text "Treated (total):    " as result `T_total'
di as text "Treated (retained): " as result `T_ret'
di as text "Controls (retained):" as result `C_ret'
di as text "Units in xtreg:     " as result `Units_ret'
di as text "Obs in xtreg:       " as result `Obs_ret'

di as text "---- Kernel balance summary ----"
di as text "mean|SMD| after=" as result %9.4f `k_mean' ///
   as text "  max|SMD| after=" as result %9.4f `k_max'

*============================================================
* Weight diagnostics
*============================================================

* Distirbution of mw (kernel weight normalizado) in retained controls (pre)
preserve
    keep if treatment==0 & matched==1 & treated==0 & mw<.
    quietly summarize mw, detail
    di as text "mw (controls, pre): p50=" %9.6f r(p50) "  p90=" %9.6f r(p90) ///
                 "  p99=" %9.6f r(p99) "  max=" %9.6f r(max)
restore

* Distribution of final weights w = padron*mw (retained controls, pre)
preserve
    keep if treatment==0 & matched==1 & treated==0 & w<.
    quietly summarize w, detail
    di as text "w=padron*mw (controls, pre): p50=" %12.2f r(p50) "  p90=" %12.2f r(p90) ///
                 "  p99=" %12.2f r(p99) "  max=" %12.2f r(max)
restore



*******************
*** Entropy Balance 
*******************
clear
use base.dta

*----------------------------
* 0) Pre versions (
*----------------------------
bysort unit_id: egen votos_cambiemos_2017_pre = max(cond(treatment==0, votos_cambiemos_2017, .))
bysort unit_id: egen votos_cambiemos_2015_pre = max(cond(treatment==0, votos_cambiemos_2015, .))

* Covariates for trimming + EB + balance
local X    votos_cambiemos_2017_pre votos_cambiemos_2015_pre nbi secundario_prop edad_65_prop extranjero_prop jxc_mayor
local Xbal `X'

*============================================================
* 1) PRE-TRIMMING por overlap en pscore 
*============================================================

tempfile keepfile

preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1

    * Drop missing in X (for logit)
    foreach v of local X {
        drop if missing(`v')
    }

    logit treated `X' [iw=padron]
    predict double pscore, pr

    quietly summarize pscore if treated==1, detail
    local loT = r(p1)
    local hiT = r(p99)

    quietly summarize pscore if treated==0, detail
    local loC = r(p1)
    local hiC = r(p99)

    local lo = max(`loT', `loC')
    local hi = min(`hiT', `hiC')

    gen byte keep_pre = inrange(pscore, `lo', `hi')
    keep unit_id keep_pre
    save `keepfile', replace
restore

merge m:1 unit_id using `keepfile', nogen

* Apply trimming
keep if keep_pre==1
drop keep_pre

*============================================================
* 2) ENTROPY BALANCING 
*============================================================

tempfile wfile

preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1

    * Drop missing in X (para EB)
    foreach v of local X {
        drop if missing(`v')
    }

    cap which ebalance
    if _rc ssc install ebalance, replace

    ebalance treated `X', targets(1) generate(w_eb)

    keep unit_id w_eb
    save `wfile', replace
restore

merge m:1 unit_id using `wfile', keepusing(w_eb) nogen

* EB-support
gen byte eb_keep = (treated==1) | (treated==0 & w_eb<.)
keep if eb_keep==1

*============================================================
* 3) CAP in EB weights, p99 of w_eb
*============================================================

preserve
    keep if treatment==0 & treated==0 & w_eb<.
    quietly summarize w_eb, detail
    local cap = r(p99)
restore

replace w_eb = `cap' if treated==0 & w_eb>`cap' & w_eb<.

*============================================================
* 4) w_final_eb = padron * w_eb (controls)
*============================================================

gen double w_final_eb = padron
replace w_final_eb = padron * w_eb if treated==0

assert w_final_eb<.

xtset unit_id treatment
xtreg votos_cambiemos_share did i.province#i.treatment [aw=w_final_eb], fe cluster(unit_id)

local Obs_ret   = e(N)
local Units_ret = e(N_g)

*============================================================
* Diagnostics
*============================================================

* (A) Treated total baseline 
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1
    local T_total = r(N)
restore

* (B) Treated/controls retained (EB-support)
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1 & eb_keep==1
    local T_ret = r(N)
    count if treated==0 & eb_keep==1
    local C_ret = r(N)
restore

di as text "---- EB (trim+cap) diagnostics ----"
di as text "Treated (total, pre):    " as result `T_total'
di as text "Treated (retained, pre): " as result `T_ret'
di as text "Controls (retained, pre):" as result `C_ret'
di as text "Units in xtreg:          " as result `Units_ret'
di as text "Obs in xtreg:            " as result `Obs_ret'
di as text "Cap applied to w_eb (p99): " as result %9.6f `cap'

*============================================================
* BALANCE (AFTER): mean/max |SMD| using w_eb 
* SMD(x) = (mean_T - mean_Cw) / sd_T, in PRE 
*============================================================

preserve
    keep if treatment==0 & eb_keep==1
    bysort unit_id: keep if _n==1

    tempname sum_abs max_abs
    scalar `sum_abs' = 0
    scalar `max_abs' = 0
    local K 0

    foreach v of local Xbal {
        quietly summarize `v' if treated==1
        local mt  = r(mean)
        local sdt = r(sd)

        quietly summarize `v' [aw=w_eb] if treated==0 & w_eb<.
        local mcw = r(mean)

        if (`sdt'>0 & `sdt'<.) {
            local smd = abs((`mt' - `mcw')/`sdt')
            scalar `sum_abs' = `sum_abs' + `smd'
            if (`smd' > `max_abs') scalar `max_abs' = `smd'
            local ++K
        }
        else {
            di as text "Warning: SD treated=0 o missing para `v' (salteado en SMD)"
        }
    }

    local eb_mean = `=scalar(`sum_abs')/`K''
    local eb_max  = `=scalar(`max_abs')'

    di as text "---- EB (trim+cap) balance summary ----"
    di as text "mean|SMD| after=" as result %9.4f `eb_mean' ///
       as text "  max|SMD| after=" as result %9.4f `eb_max'
restore

*============================================================
* WEIGHTS: p90/p99/max + ESS (controls) using w_eb y w_final_eb
*============================================================

* (1) w_eb (controls, pre)
preserve
    keep if treatment==0 & eb_keep==1 & treated==0 & w_eb<.
    quietly summarize w_eb, detail
    local eb_p90  = r(p90)
    local eb_p99  = r(p99)
    local eb_maxw = r(max)

    gen double w2 = w_eb^2
    quietly summarize w_eb
    local sw = r(sum)
    quietly summarize w2
    local sw2 = r(sum)
    local eb_ess = (`sw'^2)/`sw2'
restore

* (2) w_final_eb (controls, pre)
preserve
    keep if treatment==0 & eb_keep==1 & treated==0 & w_final_eb<.
    quietly summarize w_final_eb, detail
    local ebW_p90  = r(p90)
    local ebW_p99  = r(p99)
    local ebW_maxw = r(max)
restore

di as text "---- EB (trim+cap) weights ----"
di as text "Weights (w_eb): p90=" as result %9.6f `eb_p90' ///
           as text " p99=" as result %9.6f `eb_p99' ///
           as text " max=" as result %9.6f `eb_maxw' ///
           as text " ESS=" as result %9.2f `eb_ess'
di as text "Weights (w_final_eb): p90=" as result %12.2f `ebW_p90' ///
           as text " p99=" as result %12.2f `ebW_p99' ///
           as text " max=" as result %12.2f `ebW_maxw'


**********
* DRIPW DD 
**********
clear
use base.dta

* 1) PRE versions
bysort unit_id: egen votos_cambiemos_2017_pre = max(cond(treatment==0, votos_cambiemos_2017, .))
bysort unit_id: egen votos_cambiemos_2015_pre = max(cond(treatment==0, votos_cambiemos_2015, .))

count if treatment==0
count if missing(votos_cambiemos_2017_pre) & treatment==0
count if missing(votos_cambiemos_2015_pre) & treatment==0

* --- Covariates (pre) ---
local X votos_cambiemos_2017_pre votos_cambiemos_2015_pre nbi secundario_prop edad_65_prop extranjero_prop jxc_mayor
tempfile psfile

* --- 1) Estimate pscore in PRE and build common support ---
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1

    logit treated `X' [iw=padron]
    predict double pscore, pr

    * Common support = tratado/control instersection in pscore
    * (trimming: p1–p99 )
    quietly summarize pscore if treated==1, detail
    local loT = r(p1)
    local hiT = r(p99)

    quietly summarize pscore if treated==0, detail
    local loC = r(p1)
    local hiC = r(p99)

    local lo = max(`loT', `loC')
    local hi = min(`hiT', `hiC')

    gen byte keep_id = inrange(pscore, `lo', `hi')
    keep unit_id keep_id
    save "`psfile'", replace
restore

* --- 2) Apply support ---
merge m:1 unit_id using "`psfile'", nogen
keep if keep_id==1
gen byte dr_keep = 1
drop keep_id

* ------------------------------------------------------------
* PROVINCE × ELECTION FE: 
* ------------------------------------------------------------
tempfile provmeans
preserve
    keep province treatment votos_cambiemos_share padron
    gen double y_w = votos_cambiemos_share * padron
    collapse (sum) y_w (sum) w=padron, by(province treatment)
    gen double ybar_pt = y_w / w
    keep province treatment ybar_pt
    save `provmeans', replace
restore

merge m:1 province treatment using `provmeans', nogen
gen double votos_cambiemos_share_fept = votos_cambiemos_share - ybar_pt
drop ybar_pt

* --- 3) Estimate DRIPW DiD with drdid ---
cap which drdid
if _rc ssc install drdid, replace

drdid votos_cambiemos_share_fept `X' [iw=padron], ///
    ivar(unit_id) time(treatment) treat(treated) ///
    dripw vce(cluster unit_id)

	
*============================================================
* Diagnostics
* (DRIPW, trimmed)
*============================================================

* (A) Treated total (baseline)
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1
    local T_total = r(N)
restore

* (B) Treated / Controls retained
preserve
    keep if dr_keep==1
    keep if treatment==0
    bysort unit_id: keep if _n==1
    count if treated==1
    local T_ret = r(N)
    count if treated==0
    local C_ret = r(N)
restore

* (C) Obs retained
local Obs_ret = e(N)

di as text "---- DRIPW diagnostics ----"
di as text "Treated (total):    " as result `T_total'
di as text "Treated (retained): " as result `T_ret'
di as text "Controls (retained):" as result `C_ret'
di as text "Obs in drdid:       " as result `Obs_ret'
di as text "Trimming range (pscore): [" %9.6f `lo' ", " %9.6f `hi' "]"


*============================================================
* WEIGHT DIAGNOSTICS for "WEIGHT CONCENTRATION"
*============================================================

preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1

    * Re-estimate pscore 
    logit treated `X' [iw=padron]
    predict double pscore_diag, pr

    * Trimming
    keep if inrange(pscore_diag, `lo', `hi')

    * IPW component for ATET/ATT: w_ipw = p/(1-p)
    gen double w_ipw = pscore_diag/(1-pscore_diag)

    * === percentiles / max de w_ipw  ===
    quietly summarize w_ipw if treated==0 & w_ipw<., detail
    local dr_p90  = r(p90)
    local dr_p99  = r(p99)
    local dr_maxw = r(max)

    * === ESS using w_ipw ===
    gen double w_ipw2 = w_ipw^2
    quietly summarize w_ipw if treated==0 & w_ipw<.
    local sw  = r(sum)
    quietly summarize w_ipw2 if treated==0 & w_ipw2<.
    local sw2 = r(sum)
    local dr_ess = (`sw'^2)/`sw2'

    * Optional
    gen double w_ipw_final = padron * w_ipw
    quietly summarize w_ipw_final if treated==0 & w_ipw_final<., detail
    local drF_p90  = r(p90)
    local drF_p99  = r(p99)
    local drF_maxw = r(max)

    di as text "---- DRIPW (IPW component) weights, controls in PRE (trimmed) ----"
    di as text "w_ipw = p/(1-p): p90=" as result %9.6f `dr_p90' ///
               as text "  p99=" as result %9.6f `dr_p99' ///
               as text "  max=" as result %9.6f `dr_maxw' ///
               as text "  ESS=" as result %9.2f `dr_ess'

    di as text "w_ipw_final = padron*w_ipw: p90=" as result %12.2f `drF_p90' ///
               as text "  p99=" as result %12.2f `drF_p99' ///
               as text "  max=" as result %12.2f `drF_maxw'
restore
*============================================================
* Pscore distirbution in pre trimmed 
*============================================================
preserve
    keep if treatment==0
    bysort unit_id: keep if _n==1
    logit treated `X' [iw=padron]
    predict double pscore_diag2, pr
    keep if inrange(pscore_diag2, `lo', `hi')

    quietly summarize pscore_diag2 if treated==1, detail
    di as text "pscore (treated, pre, trimmed): p1=" %9.6f r(p1) " p50=" %9.6f r(p50) " p99=" %9.6f r(p99)

    quietly summarize pscore_diag2 if treated==0, detail
    di as text "pscore (control, pre, trimmed): p1=" %9.6f r(p1) " p50=" %9.6f r(p50) " p99=" %9.6f r(p99)
restore

